<template>
  <Search :schema="schema" @search="search" @reset="reset" />
  <BaseButton class="mb-20px" type="primary" @click="add">新增</BaseButton>
  <Table
    v-model:pageSize="pageSize"
    v-model:currentPage="currentPage"
    :columns="tableColums"
    :data="dataList"
    row-key="id"
    :loading="loading"
    height="600"
    sortable
    :pagination="{ total: total }"
    @register="tableRegister"
  />
  <Dialog :title="title" v-model="visible" @close="visible = false">
    <Form :schema="formItem" @register="formRegister" :rules="rules" />
    <template #footer>
      <BaseButton type="primary" @click="FormSubmit">提交</BaseButton>
      <BaseButton type="primary" @click="visible = false">取消</BaseButton>
    </template>
  </Dialog>
  <Dialog title="修改密码" v-model="visiblePassWd" @close="visiblePassWd = false">
    <ElForm ref="ruleFormRef" :rules="passRules" :model="formPassWd">
      <ElFormItem label="新密码" prop="password">
        <InputPassword class="w-[60%]" v-model="formPassWd.password" :strength="true" />
      </ElFormItem>
    </ElForm>
    <div class="flex">
      <BaseButton class="mt-10px mb-10px" type="primary" @click="generatePassWd">
        生成强密码
      </BaseButton>
      <BaseButton class="mt-10px mb-10px" type="primary" @click="copySecret"> 复制密码 </BaseButton>
    </div>
    <div>密码最少8位，最多16位，需由大写字母、小写字母和特殊字符混合组成。</div>
    <template #footer>
      <BaseButton type="primary" @click="submitPassWd(ruleFormRef)">确定</BaseButton>
      <BaseButton type="primary" @click="visiblePassWd = false">取消</BaseButton>
    </template>
  </Dialog>
</template>

<script lang="tsx" setup>
import { ref } from 'vue'
import { TableColumn, Table } from '@/components/Table'
import { ElMessage, ElMessageBox } from 'element-plus'
import { BaseButton } from '@/components/Button'
import { useTable } from '@/hooks/web/useTable'
import { Search } from '@/components/Search'
import { Dialog } from '@/components/Dialog'
import { ElForm, ElFormItem, FormInstance } from 'element-plus'
import { InputPassword } from '@/components/InputPassword'
import { FormSchema, Form } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { useValidator } from '@/hooks/web/useValidator'
import { formatToDateTime } from '@/utils/dateUtil'
import { switchStyle } from '@/utils/color'
import { innerWidth, formItemWidth, globalWidth } from '@/utils/styles'
import useClipboard from 'vue-clipboard3'
import { listApi, addAdminApi, updateAdminApi } from '@/api/admin'

// ----------------------搜索区域 start----------------------------------
const schema = ref<FormSchema[]>([
  {
    field: 'name',
    component: 'Input',
    componentProps: {
      placeholder: '请输入真实姓名',
      clearble: true
    }
  },
  {
    field: 'email',
    component: 'Input',
    componentProps: {
      placeholder: '请输入邮箱',
      clearble: true
    }
  },
  {
    field: 'is_enabled',
    component: 'Select',
    componentProps: {
      placeholder: '请选择状态',
      options: [
        {
          label: '启用',
          value: 1
        },
        {
          label: '禁用',
          value: 0
        }
      ]
    }
  }
])

const searchParams = ref({})
const search = (form: any) => {
  searchParams.value = form
  currentPage.value = 1
  getList()
}

const reset = () => {
  // 将所有搜索值设置为空
  schema.value.forEach((item) => {
    item.value = ''
  })
  searchParams.value = {}
  currentPage.value = 1
  getList()
}
// ----------------------搜索区域 end------------------------------------

// ----------------------表格区域 start----------------------------------
const tableColums = ref<TableColumn[]>([
  {
    field: 'id',
    label: 'ID'
  },
  {
    field: 'name',
    label: '真实姓名',
    slots: {
      default: (scope: any) => {
        return <>{scope.row.name}</>
      }
    }
  },
  {
    field: 'email',
    label: '邮箱',
    slots: {
      default: (scope: any) => {
        return <>{scope.row.email}</>
      }
    }
  },
  {
    field: 'phone',
    label: '手机号',
    slots: {
      default: (scope: any) => {
        return <>{scope.row.phone}</>
      }
    }
  },
  {
    field: 'gender',
    label: '性别',
    slots: {
      default: (scope: any) => {
        return <>{scope.row.gender === 1 ? '男' : '女'}</>
      }
    }
  },
  {
    field: 'is_enabled',
    label: '账号状态',
    slots: {
      default: (scope: any) => {
        return <>{scope.row.is_enabled ? '启用' : '禁用'}</>
      }
    }
  },
  {
    field: 'created_at',
    label: '创建时间',
    slots: {
      default: (scope: any) => {
        return <>{formatToDateTime(scope.row.created_at)}</>
      }
    }
  },
  {
    field: 'operations',
    label: '操作',
    width: '250px',
    show: true,
    slots: {
      default: (scope: any) => {
        return (
          <>
            <BaseButton type="primary" onClick={() => edit(scope.row)}>
              编辑
            </BaseButton>
            <BaseButton type="primary" onClick={() => editPassWd(scope.row)}>
              修改密码
            </BaseButton>
          </>
        )
      }
    }
  }
])
// 引入tablemethods，包括getList
const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const { currentPage, pageSize } = tableState
    console.log('currentPage', currentPage.value, 'pageSize', pageSize.value)

    const res = await listApi<any, IAdmin>({
      page: currentPage.value,
      pageSize: pageSize.value,
      ...searchParams.value
    })
    console.log('res', res)
    const { data } = res
    const ans = {
      list: data.items,
      total: data.total
    }
    return ans
  }
})

const { loading, dataList, total, currentPage, pageSize } = tableState
const { getList } = tableMethods
// const { t } = useI18n()
// ----------------------表格区域 end------------------------------------

// ----------------------dialog区域 start--------------------------------
// 管理员列表标题
const title = ref('新增管理员')
// 新增/修改控件
const isAdd = ref(true)
// 管理员弹窗控件
const visible = ref(false)
// 修改密码弹窗控件
const visiblePassWd = ref(false)
// 修改密码的变量值
const formPassWd = ref({
  password: '',
  id: 0,
  phone: ''
})

// 修改密码弹窗打开
function editPassWd(e: IAdmin) {
  visiblePassWd.value = true
  formPassWd.value = {
    password: e.password as string,
    id: e.id,
    phone: e.phone
  }
}

function add() {
  title.value = '添加管理员'
  isAdd.value = true
  const password = {
    field: 'password',
    label: '密码',
    component: 'InputPassword',
    colProps: formItemWidth,
    componentProps: {
      placeholder: '请输入密码'
    }
  }
  formItem.value.push(password as FormSchema)
  formItem.value.forEach((item) => {
    if (item.field === 'password') {
      item.value = 'xyzzsdheal12'
    } else {
      item.field === 'isEnabled' ? (item.value = true) : (item.value = '')
    }
  })
  visible.value = true
}

const delPassWd = (): FormSchema[] => {
  const newItem = ref<FormSchema[]>([])
  for (const item of formItem.value) {
    if (item.field !== 'password') {
      newItem.value.push(item)
    }
  }
  return newItem.value as FormSchema[]
}

function edit(e: IAdmin) {
  title.value = '编辑管理员'
  isAdd.value = false
  formItem.value = delPassWd()
  formItem.value.forEach((item) => {
    if (item.field === 'isEnabled') {
      item.value = e[item.field] === 0 ? false : true
    } else {
      item.value = e[item.field]
    }
  })
  visible.value = true
}
// ----------------------dialog区域 end------------------------------------
// ----------------------表单区域 start------------------------------------
// 表单提交
async function FormSubmit() {
  const res = await formMethods.getFormData()
  const resExpose = await formMethods.getElFormExpose()
  const valid = await resExpose?.validate()
  if (valid) {
    isAdd.value ? delete res.id : ''
    const ans = await (isAdd.value ? addAdminApi(res) : updateAdminApi(res))
    if (ans.code === 200) {
      ElMessage.success('操作成功')
      getList()
    }
    currentPage.value = 1
    visible.value = false
  }
}
// 表单结构
const formItem = ref<FormSchema[]>([
  {
    field: 'id',
    hidden: true
  },
  {
    field: 'name',
    label: '真实姓名',
    component: 'Input',
    colProps: formItemWidth,
    componentProps: innerWidth('请输入真实姓名')
  },
  {
    field: 'isEnabled',
    label: '是否启用',
    component: 'Switch',
    colProps: formItemWidth,
    componentProps: {
      style: switchStyle
    }
  },
  {
    field: 'phone',
    label: '手机号',
    component: 'Input',
    colProps: formItemWidth,
    componentProps: innerWidth('请输入手机号')
  },
  {
    field: 'email',
    label: '邮箱',
    component: 'Input',
    colProps: formItemWidth,
    componentProps: innerWidth('请输入邮箱')
  },
  {
    field: 'gender',
    label: '性别',
    component: 'Select',
    colProps: formItemWidth,
    componentProps: {
      style: globalWidth,
      placeholder: '请选择性别',
      filterable: true,
      clearble: true,
      options: [
        {
          label: '男',
          value: 1
        },
        {
          label: '女',
          value: 2
        }
      ]
    }
  },
  {
    field: 'age',
    label: '年龄',
    component: 'InputNumber',
    colProps: formItemWidth,
    componentProps: {
      style: globalWidth,
      placeholder: '请输入年龄'
    }
  }
])
// 表单校验
const { required } = useValidator()
// 自定义校验规则：手机号验证
const validPhone = (rule, value, callback) => {
  console.log('🚀 ~ validPhone ~ rule:', rule)
  if (!value) {
    return callback(new Error('请输入手机号'))
  }
  if (!/^1[3456789]\d{9}$/.test(value)) {
    return callback(new Error('请输入正确的手机号'))
  }
  callback()
}

const rules = ref({
  userName: [required('')],
  phone: [{ required: true, validator: validPhone, trigger: 'blur' }],
  isEnabled: [required('')],
  password: [required('')]
})
const { formRegister, formMethods } = useForm()

// 修改密码表单的校验
const ruleFormRef = ref<FormInstance>()
const passRules = ref({
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
})

// 生成修改密码中强密码
function generatePassWd() {
  formPassWd.value.password = 'sihsicdb112'
}

// 复制强密码到剪切板
const { toClipboard } = useClipboard()
async function copySecret() {
  // window.clipboardData.setData("Text", txt)
  // 此处使用原生剪切板对象的话，会出现类型“Window & typeof globalThis”上不存在属性“clipboardData”。ts(2339)错误，所以引入第三方库
  // 复制元素到剪切板
  try {
    await toClipboard(formPassWd.value.password)
    ElMessage.success('复制成功')
  } catch (error) {
    console.log('🚀 ~ copySecret ~ error:', error)
    ElMessage.error('复制失败')
  }
}

function onEditPasswd(params: { password: string; id: number; phone: string }) {
  ElMessageBox.confirm('确定修改密码？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      await updateAdminApi(params)
      ElMessage.success('修改成功')
      visiblePassWd.value = false
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '已取消'
      })
    })
}

// 修改密码表单提交
async function submitPassWd(formEl: FormInstance | undefined) {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    console.log('🚀 ~ awaitformEl.validate ~ fields:', fields)
    if (valid) {
      onEditPasswd(formPassWd.value)
    }
  })
}
// ----------------------表单区域 end------------------------------------
</script>
